<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>2048</title>
    <!--初始化,第一个数字生成,左右移动,第二个数字生成-->
</head>
<style>
    #main {
        width: 400px;
        height: 400px;
        background: #99CCFF;
        table-layout: fixed;
        border-spacing: 0;
        border-collapse: separate;
    }

    #main tr {
        height: 25%;
    }

    #main td {
        border: 1px solid #fff;
    }

    #main td div {
        width: 100%;
        height: 100%;
        line-height: 94px;
        text-align: center;
        font-size: 35px;
        font-weight: bold;
        transition: all 1s;
        background-color: #fdfdfc;
    }

    .rank2 {
        color: #cac7c5;
    }

    .rank4 {
        color: #d2b19b;
    }

    .rank8 {
        color: #d2a384;
    }

    .rank16 {
        color: #d29369;
    }

    .rank32 {
        color: #d2804a;

    }

    .rank64 {
        color: #d07438;
    }

    .rank128 {
        color: #d0641e;
    }

    .rank256 {
        color: #cc5407
    }

    .rank512 {
        color: #c73806;
    }

    .rank1024 {
        color: #da3d07
    }

    .rank2048 {
        color: #f34104
    }
</style>
<body>
<table id="main">
    <tr>
        <td></td>
        <td></td>
        <td></td>
        <td></td>
    </tr>
    <tr>
        <td></td>
        <td></td>
        <td></td>
        <td></td>
    </tr>
    <tr>
        <td></td>
        <td></td>
        <td></td>
        <td></td>
    </tr>
    <tr>
        <td></td>
        <td></td>
        <td></td>
        <td></td>
    </tr>
</table>
</body>
<script>
    let arr = [
        [0, 2, 8, 2],
        [0, 0, 8, 8],
        [64, 0, 0, 0],
        [0, 0, 0, 0]
    ];
    let elementRow = document.querySelectorAll('#main tr');

    function getOne() {
        return (Math.random() - 0.5) > 0 ? 2 : 4;
    }

    function addOne() {
        let result = [];
        for (let i = 0; i < 4; i++) {
            for (let j = 0; j < 4; j++) {
                if (!arr[i][j]) {
                    result.push({i, j});
                }
            }
        }
        if(result.length === 0){
            return;//暂时,无法添加新元素时失败
        }
        let {i, j} = result[(result.length * Math.random()) | 0];
        let fillNumber = getOne();
        arr[i][j] = fillNumber;
        let currentRow = elementRow[i].children;
        currentRow[j].innerHTML = `<div class="rank${fillNumber}">${fillNumber}</div>`;
    }

    function render() {
        for (let i = 0; i < 4; i++) {
            for (let j = 0; j < 4; j++) {
                if (arr[i][j]) {
                    elementRow[i].children[j].innerHTML = `<div class="rank${arr[i][j]}">${arr[i][j]}</div>`;
                }else{
                    elementRow[i].children[j].innerHTML = ''
                }
            }
        }
    }

    function init() {
        render();//初始渲染;
        addOne();//先添加一个;
    }

    function operationLeft() {
        for (let i = 0; i < 4; i++) {
            leftRight(i,false);
            let delArr = [];
            for(let j=0;j<4;j++){
                if(!arr[i][j]){
                    delArr.push(j);
                }
            }
            let c = delArr.length;
            while (c--){
                arr[i].splice(delArr[c],1);
                arr[i].push(0);
            }

        }

    }

    function operationRight() {
        for (let i = 0; i < 4; i++) {

            leftRight(i,true);

            let delArr = [];
            let j = 4;
            while (j--){
                if (!arr[i][j]) {
                    delArr.push(j);
                }
            }
            let c = delArr.length;
            while(c--){
                arr[i].splice(delArr[c], 1);
                arr[i].unshift(0);
            }
        }

    }

    function leftRight(i,isRight) {
        let repeat = checkRepeat(arr[i]);
        if (repeat.length !== 0) {
            for (let k = 0; k < repeat.length; k++) {
                let {originPos, repeatPos} = repeat[k];
                let offset = isRight ? repeatPos - originPos : originPos - repeatPos;
                let moveDiv = elementRow[i].children[isRight?originPos:repeatPos].getElementsByTagName('div')[0];
                moveDiv.style.transform = `translateX(${offset * 100}px)`;
                arr[i].splice(isRight?originPos:repeatPos, 1, 0);
                arr[i][isRight?repeatPos:originPos] *= 2;
            }
        }
    }

    function checkRepeat(checkArr) {
        let result = [];
        function addResult(j,num) {
            if (checkArr[j] === checkArr[j + num]) {
                return result.push({
                    originPos: j,
                    repeatPos: j + num
                });
            }
            return false;
        }
        for (let j = 0; j < 3; j++) {
            if (checkArr[j]) {//不为0
                if(j<3&&checkArr[j+1]){
                    if(addResult(j,1)){
                        j+=1;
                        continue;
                    }
                }else if(j<2&&checkArr[j+2]){
                    if(addResult(j,2)){
                        j+=2;
                        continue;
                    }
                }else if(j<1&&checkArr[j+3]){
                    if(addResult(j,3)){
                        continue;
                    }
                }
            }
        }
        return result;
        //result  重复的位置  如 {2:1} 这一行 第二个和第三个是重复的,可以出现多次;
    }

    document.addEventListener('keydown', function (e) {
        if (e && e.keyCode === 37) {
            //左
            operationLeft();
            setTimeout(()=>{
                init();
            },700);
        }
        if (e && e.keyCode === 38) {
            //上
        }

        if (e && e.keyCode === 39) {
            //右
            operationRight();
            setTimeout(()=>{
                init();
            },700);
        }
        if (e && e.keyCode === 40) {
            //下
        }
    }, false);

    init();
</script>
</html>